// var server = "https://mrcpserver.7moor.com:8089/janus";

//走阿里云内网的slb
import { Janus } from './janus'
// var server = "https://webqhbalislb.7moor.com:8092/janus"
var server = 'https://janus-ykf.7moor.com/janus'
//走外网的slb
var server_waiwang = "https://janus-ykf.7moor.com/janus"

var janus = null;
var sipcall = null;
var opaqueId = "7moorSip-" + Janus.randomString(12)

var started = false
var spinner = null

var selectedApproach = "secret"
var registered = false

var incoming = null

var media_server = null

var current_jsep = null
var current_result = null

var reconnect_set_time_out = null

var m7webPhoneUtils = {
    qhbUrl: 'https://test.7moor.com:9443',
    kickSocketUrl: 'wss://ccpclient.7moor.com/ws',
    kickSocket: null,
    _isKicked: false,
    setKickSocket: function (kickToken) {
        m7webPhoneUtils.kickSocket = new WebSocket(m7webPhoneUtils.kickSocketUrl);
        m7webPhoneUtils.kickSocket.onopen = function () {
            console.log("Socket has been opened");
            console.log("{\"flag\": \"qhb\", \"user\": \"" + kickToken + "\"}")
            m7webPhoneUtils.kickSocket.send("{\"flag\": \"qhb\", \"user\": \"" 
            + kickToken + "\"}")
        }
        m7webPhoneUtils.kickSocket.onmessage = function (msg) {
            if (msg.data === 'kick') {
                m7webPhoneUtils._isKicked = true
                if (m7WebPhone.onMessage && typeof m7WebPhone.onMessage === 'function') {
                    m7WebPhone.onMessage('kicked')
                }
            }
        }
        m7webPhoneUtils.kickSocket.onclose = function () {
            console.log("Socket has been closed");
            m7WebPhone.onError({type:'socket', error: "Socket has been closed"})

        }
        m7webPhoneUtils.kickSocket.onerror = function (err) {
            console.log(err)
            console.log('socket error')
            m7WebPhone.onError({type:'socket', error: err})
        }
    },
    sendPostCommand: function (command, callback, errorCallback, async, timeout) {
        
        let data = command.data
        command.data = data
        const qhbUrl = command.qhbUrl || 'https://webphone.7moor.com/'
        window.fetch( qhbUrl + '/action', {
          method: 'POST',
          body: 'action=' + command.action + '&data=' + JSON.stringify(command.data),
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        }).then((res) => {
          return res.json()
        }).then((res) => {
            callback(res)
        }).catch((res) => {
          console.log(res)
          m7WebPhone.onError('sendPostError: ' + res)
        })
    }
}
var m7WebPhone = {
    onMessageCallback: null,
    initCallback: null,
    onError: null,
    loginQhbWebPhone: function (loginData) {
        var kickToken = loginData.username + '-' + new Date().getTime()
        var action = {
            'action': 'softphone.loginNoCode',
            'data': {
                'loginName': loginData.username,
                'password': loginData.pwd,
                'kickToken': kickToken
            },
            'qhbUrl': loginData.qhbUrl || 'https://webphone.7moor.com/'
        }
        m7webPhoneUtils.sendPostCommand(action, function (response) {
            // m7webPhoneUtils.setKickSocket(kickToken)
            console.log('final: media_ip=' + response.media_ip + ';janus_server=' + server + ';assDomain=' + response.assDomain);
            media_server = response.media_ip + ':' + response.media_port;
            console.log('sip:' + media_server, 'sip:' + response.sip_id + '@' + media_server, response.sip_id, response.sip_pwd, response.sip_id)
            m7WebPhone.media_server = media_server;
            m7WebPhone.sip_id = response.sip_id;
            m7WebPhone.sip_pwd = response.sip_pwd;
            m7WebPhone.initWebSipPhone('sip:' + media_server, 'sip:' + response.sip_id + '@' + media_server, response.sip_id, response.sip_pwd, response.sip_id);
        }, function(err){
            m7WebPhone.onError(err)
        })
    },
    initWebSipPhone: function (media_server, media_username, media_authuser, media_pwd, media_dispalyname) {
        // Initialize the library (all console debuggers enabled)
        Janus.init({
            callback: function () {
                // Use a button to start the demo
                if (started)
                    return;
                started = true;
                // Make sure the browser supports WebRTC
                if (!Janus.isWebrtcSupported()) {
                    // alert("No WebRTC support... ")
                    m7WebPhone.onMessage('no_webrtc');
                    return;
                }
                // Create session
                janus = new Janus(
                    {   
                        withCredentials: true,
                        server: server,
                        // withCredentials: true,
                        success: function () {
                            // Attach to echo test plugin
                            janus.attach(
                                {
                                    plugin: "janus.plugin.sip",
                                    opaqueId: opaqueId,
                                    success: function (pluginHandle) {
                                        // $('#details').remove();
                                        sipcall = pluginHandle;
                                        // m7WebPhone.initCallback(pluginHandle)
                                        Janus.log("Plugin attached! (" + sipcall.getPlugin() + ", id=" + sipcall.getId() + ")");
                                        selectedApproach = 'secret';
                                        registerUsername(media_server, media_username, media_authuser, media_pwd, media_dispalyname);
                                    },
                                    error: function (error) {
                                        // alert('初始化软电话失败！');
                                        m7WebPhone.onError(error)
                                        // Janus.error("  -- Error attaching plugin...", error);
                                        // bootbox.alert("  -- Error attaching plugin... " + error);
                                    },
                                    consentDialog: function (on) {
                                        Janus.debug("Consent dialog should be " + (on ? "on" : "off") + " now");
                                    },
                                    onmessage: function (msg, jsep) {
                                        current_jsep = jsep;
                                        if (m7WebPhone.onMessage && typeof m7WebPhone.onMessage === 'function') {
                                            var backMsg
                                            if (msg['result']['event'] === 'incomingcall') {
                                                if (msg['result']["displayname"].replace(/"/g, "") === 'asterisk') {
                                                    backMsg = 'Outbound'
                                                } else {
                                                    backMsg = 'incomingcall'
                                                }
                                            } else {
                                                backMsg = msg['result']['event']
                                            }
                                            m7WebPhone.onMessage(backMsg)
                                        }
                                        Janus.debug(" ::: Got a message :::");
                                        Janus.debug(msg);
                                        // Any error?
                                        var error = msg["error"];
                                        if (error != null && error != undefined) {
                                            if (!registered) {
                                                
                                            } else {
                                                // Reset status
                                                sipcall.hangup();
                                            }
                                            alert(error);
                                            return;
                                        }
                                        var result = msg["result"];
                                        current_result = result
                                        if (result !== null && result !== undefined && result["event"] !== undefined && result["event"] !== null) {
                                            var event = result["event"];
                                            if (event === 'registration_failed') {
                                                Janus.warn("Registration failed: " + result["code"] + " " + result["reason"]);
                                                // 登录话机失败
                                                return;
                                            }
                                            if (event === 'registered') {
                                                // 登录话机成功
                                                Janus.log("Successfully registered as " + result["username"] + "!");
                                                // TODO Enable buttons to call now
                                                if (!registered) {
                                                    registered = true;
                                                }
                                            } else if (event === 'calling') {
                                                Janus.log("Waiting for the peer to answer...");
                                                // TODO Any ringtone?
                                            } else if (event === 'incomingcall') {
                                                // 有来电或外呼
                                                incoming = true
                                                Janus.log("Incoming call from " + result["username"] + "!");
                                                var callerNum = result["displayname"].replace(/"/g, "");
                                                if (callerNum === 'asterisk') {
                                                    // 外呼
                                                    window.setTimeout(function () {
                                                        m7WebPhone.AnswerCall()
                                                    }, 300)
                                                }
                                            } else if (event === 'accepting') {
                                                // Response to an offerless INVITE, let's wait for an 'accepted'
                                            } else if (event === 'progress') {
                                                Janus.log("There's early media from " + result["username"] + ", wairing for the call!");
                                                Janus.log(jsep);
                                                // Call can start already: handle the remote answer
                                                if (jsep !== null && jsep !== undefined) {
                                                    sipcall.handleRemoteJsep({jsep: jsep, error: doHangup});
                                                }
                                                toastr.info("Early media...");
                                            } else if (event === 'accepted') {
                                                var ringingTone = document.getElementById('webrtc_calleering')
                                                if(ringingTone){
                                                    ringingTone.pause()
                                                }
                                                Janus.log(result["username"] + " accepted the call!");
                                                Janus.log(jsep);
                                                // Call can start, now: handle the remote answer
                                                if (jsep !== null && jsep !== undefined) {
                                                    sipcall.handleRemoteJsep({jsep: jsep, error: doHangup});
                                                }
                                            } else if (event === 'hangup') {
                                                var ringingTone = document.getElementById('webrtc_calleering')
                                                if(ringingTone){
                                                  ringingTone.pause()
                                                }
                                                if (incoming != null) {
                                                    incoming.modal('hide');
                                                    incoming = null;
                                                }
                                                Janus.log("Call hung up (" + result["code"] + " " + result["reason"] + ")!");
                                                // Reset status
                                                sipcall.hangup();
                                            }
                                        }
                                    },
                                    onlocalstream: function (stream) {
                                        Janus.debug(" ::: Got a local stream :::");
                                        Janus.debug(stream);
                                        var body = document.querySelectorAll('body')[0]
                                        if(document.querySelectorAll('#myvideo').length === 0) {
                                          var video = document.createElement("video")
                                          video.setAttribute("id", "myvideo")
                                          video.setAttribute('autoplay', true)
                                          video.setAttribute('muted', 'muted')
                                          video.className = 'rounded centered'
                                          body.appendChild(video)
                                        }
                                        // m7$('body').append('<video class="rounded centered" id="myvideo" width=320 height=240 autoplay muted="muted"/>');
                                        Janus.attachMediaStream(document.getElementById('myvideo'), stream);
                                        document.getElementById("myvideo").muted = "muted";
                                        // No remote video yet
                                        if(document.querySelectorAll('#waitingvideo').length === 0) {
                                          var waitVideo = document.createElement("video")
                                          waitVideo.setAttribute('id', 'waitingvideo')
                                          waitVideo.className = 'rounded centered'
                                          body.appendChild(waitVideo)
                                        }
                                        // m7$('body').append('<video class="rounded centered" id="waitingvideo" width=320 height=240 />');
                                        var videoTracks = stream.getVideoTracks();
                                    },
                                    onremotestream: function (stream) {
                                        Janus.debug(" ::: Got a remote stream :::");
                                        Janus.debug(stream);
                                        var body = document.querySelectorAll('body')[0]
                                        if(document.querySelectorAll('#remotevideo').length === 0) {
                                          var video = document.createElement("video")
                                          video.setAttribute("id", "remotevideo")
                                          video.setAttribute('autoplay', true)
                                          body.appendChild(video)
                                        }
                                        // m7$('body').append(
                                        //     '<video class="rounded centered hide" id="remotevideo" width=320 height=240 autoplay/>');
                                        Janus.attachMediaStream(document.getElementById('remotevideo'), stream);
                                    },
                                    oncleanup: function () {
                                        Janus.log(" ::: Got a cleanup notification :::");
                                    }
                                });
                        },
                        error: function (error) {
                            Janus.error(error);
                            // alert(error, function () {
                            //     window.location.reload();
                            // });
                            m7WebPhone.onError('JanusError:'+ error)
                            if (error === 'Lost connection to the gateway (is it down?)' || (error && error.indexOf('Probably a network error, is the gateway down?') !== -1)){
                                started = false
                                if (reconnect_set_time_out) {
                                  clearTimeout(reconnect_set_time_out)
                                }
                                reconnect_set_time_out = setTimeout(function() {
                                  m7WebPhone.initWebSipPhone('sip:' + m7WebPhone.media_server, 'sip:' + m7WebPhone.sip_id + '@' + m7WebPhone.media_server, m7WebPhone.sip_id, m7WebPhone.sip_pwd, m7WebPhone.sip_id);
                                }, 2000)
                            }
                        },
                        destroyed: function () {
                            m7WebPhone.onError('JanusError: destroyed')
                            // window.location.reload();
                        }
                    });
            }
        });
    },
    AnswerCall: function () {
        if (incoming === true && current_jsep !== null && current_result !== null) {
            var doAudio = true, doVideo = true;
            var offerlessInvite = false;
            if (current_jsep !== null && current_jsep !== undefined) {
                doAudio = (current_jsep.sdp.indexOf("m=audio ") > -1);
                doVideo = (current_jsep.sdp.indexOf("m=video ") > -1);
                Janus.debug("Audio " + (doAudio ? "has" : "has NOT") + " been negotiated");
                Janus.debug("Video " + (doVideo ? "has" : "has NOT") + " been negotiated");
            } else {
                Janus.log("This call doesn't contain an offer... we'll need to provide one ourselves");
                offerlessInvite = true;
                doVideo = false;
            }
            var rtpType = "";
            var srtp = current_result["srtp"];
            if (srtp === "sdes_optional")
                rtpType = " (SDES-SRTP offered)";
            else if (srtp === "sdes_mandatory")
                rtpType = " (SDES-SRTP mandatory)";

            var extra = "";
            if (offerlessInvite)
                extra = " (no SDP offer provided)"
        }
        incoming = null;
        var sipcallAction = (offerlessInvite ? sipcall.createOffer : sipcall.createAnswer);
        sipcallAction(
            {
                jsep: current_jsep,
                media: {audio: doAudio, video: doVideo},
                success: function (jsep) {
                    Janus.debug("Got SDP " + jsep.type + "! audio=" + doAudio + ", video=" + doVideo);
                    Janus.debug(jsep);
                    var body = {request: "accept"};
                    sipcall.send({"message": body, "jsep": jsep});
                },
                error: function (error) {
                    Janus.error("WebRTC error:", error);
                    // alert("WebRTC error... " + JSON.stringify(error));
                    m7WebPhone.onError({type: 'webrtc', error: error})
                    var body = {"request": "decline", "code": 480};
                    sipcall.send({"message": body});
                }
            })
    }

}

export function initM7WebPhone(loginData) {
    this.init(loginData)
}

initM7WebPhone.prototype.onMessage = function(callback) {
    m7WebPhone.onMessage = callback
}

initM7WebPhone.prototype.onError = function(callback) {
    m7WebPhone.onError = callback
}

initM7WebPhone.prototype.init = function(loginData) {
    if (janus) {
        started = false
        janus.destroy()
    }
    m7WebPhone.loginQhbWebPhone(loginData)
}

initM7WebPhone.prototype.destroy = function(loginData) {
    if (janus) {
        started = false
        janus.destroy()
    }
}


initM7WebPhone.prototype.Outbound = function () {
    if (sipcall) {
        sipcall.createOffer({
            jsep: current_jsep,
            media: { audio: true, video: false },
            success: function(jsep){
                var body = { request: "accept" };
                sipcall.send({"message": body, "jsep": jsep});
            },
            error: function(error){
                console.log(error, 'error')
                m7WebPhone.onError(error)
            }
        })
    } else {
        m7WebPhone.onError('初始化失败')
    }
}

initM7WebPhone.prototype.doHangup = function () {
    if (sipcall) {
      let body = { "request": "decline" }
      sipcall.send({"message": body})
      let hangup = {"request": "hangup"}
      sipcall.send({"message": hangup})
      sipcall.hangup()
    }
}

function registerUsername(media_server, media_username, media_authuser, media_pwd, media_dispalyname) {
    var sipserver = media_server;

    var username = media_username;

    var password = media_pwd;

    var register = {
        "request": "register",
        "username": username
    };

    register.authuser = media_authuser;

    register.display_name = media_dispalyname;

    register["secret"] = password;

    register["proxy"] = sipserver;
    sipcall.send({"message": register});
    
}

function doHangup () {
    // Hangup a call
    m7$('#call').attr('disabled', true).unbind('click');
    var hangup = {"request": "hangup"};
    sipcall.send({"message": hangup});
    sipcall.hangup();
}
